package me.lc.linklink.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

import me.lc.linklink.entity.Location;
import me.lc.linklink.entity.StageInfo;
import me.lc.linklink.layer.GameLayer;
import me.lc.linklink.scene.GameScene;
import me.lc.linklink.sprite.LLKBlock;
import me.lc.linklink.util.ADHelper;
import me.lc.linklink.util.AudioHelper;
import me.lc.linklink.util.GameUtil;
import me.lc.linklink.util.LLKLogicHelper;
import me.lc.linklink.util.NodeMoveHelper;
import android.app.Activity;
import android.widget.Toast;

import com.wiyun.engine.nodes.Sprite;
import com.wiyun.engine.types.WYPoint;
import com.wiyun.engine.utils.ResolutionIndependent;

/**
 * 游戏地图,游戏逻辑
 * 
 * @author Administrator
 * 
 */
public class GameMap {

	/**
	 * 数据块信息
	 */
	static LLKBlock[][] blocks;

	/**
	 * 选择器信息
	 */
	static Sprite spriteSelector;
	static Sprite spriteFinder1;
	static Sprite spriteFinder2;
	static Random r = new Random((new Date()).getTime());

	/**
	 * 游戏层
	 */
	static GameLayer layer;

	/**
	 * 是否选中一个块
	 */
	static boolean isSelected = false;
	static boolean isFinderShow = false;
	static int selectRow = -1;
	static int selectColumn = -1;

	public static void init() {
		blocks = new LLKBlock[GameSystem.GameRows + 2][GameSystem.GameColumns + 2];
	}

	public static void gen(GameLayer gameLayer, int stageIndex) {
		layer = gameLayer;
		StageInfo stageInfo = StageManager.instance.stageInfos.get(stageIndex);
		// 生成地图
		for (int i = 0; i < GameSystem.GameRows + 2; i++) {
			for (int j = 0; j < GameSystem.GameColumns + 2; j++) {
				blocks[i][j] = new LLKBlock(-1);
			}
		}
		int sum = GameSystem.GameRows * GameSystem.GameColumns;
		if (sum % 2 != 0) {
			Toast.makeText(GameSystem.AndroidContext, "数据错误", 3000);
			return;
		}
		for (int i = 0; i < sum / 2; i++) {
			// int temp = r.nextInt(stageInfo.getItemCount());
			int temp = i % stageInfo.getItemCount()
					+ stageInfo.getItemStartIndex();
			for (int j = 0; j < 2; j++) {
				int randomI = r.nextInt(GameSystem.GameRows) + 1;
				int randomJ = r.nextInt(GameSystem.GameColumns) + 1;
				while (blocks[randomI][randomJ].getBlockItemIndex() != -1) {
					randomI = r.nextInt(GameSystem.GameRows) + 1;
					randomJ = r.nextInt(GameSystem.GameColumns) + 1;
				}
				blocks[randomI][randomJ].setBlockItemIndex(temp);
				Location location = new Location(randomI - 1, randomJ - 1);

				gameLayer.addChild(blocks[randomI][randomJ]);
				blocks[randomI][randomJ].setLocation(location);
			}
		}
	}

	/**
	 * 处理点击
	 * 
	 * @param point
	 */
	public static void processTouch(WYPoint point) {

		float leftMargin = ResolutionIndependent
				.resolveDp(GameSystem.Margin_Side);
		float itemSize = ResolutionIndependent.resolveDp(GameSystem.BLOCK_SIZE);
		int row, column;
		column = (int) ((point.x - leftMargin) / itemSize);
		row = (int) ((point.y - GameSystem.Start_Height) / itemSize);

		// 处理点击同一个block
		if (column == selectColumn && row == selectRow) {
			return;
		}

		if (row < GameSystem.GameRows && column < GameSystem.GameColumns
				&& row >= 0 && column >= 0 && (point.x - leftMargin) >= 0) {

			// 首先判断是否已经选中一个单元，如果是，先判断能否连接
			boolean isSameItem = false;
			int itemCurrent = blocks[row + 1][column + 1].getBlockItemIndex();
			int itemSelect = blocks[selectRow + 1][selectColumn + 1]
					.getBlockItemIndex();
			if (itemCurrent >= 0 && itemSelect >= 0
					&& itemSelect == itemCurrent) {
				isSameItem = true;
			}

			boolean isLined = false;
			if (isSelected && isSameItem) {
				isLined = LLKLogicHelper.CanEliminate(blocks, row + 1,
						column + 1, selectRow + 1, selectColumn + 1);
				if (isLined) {
					spriteSelector.setVisible(false);
					// 设置节点为空,并启动动画
					blocks[row + 1][column + 1].setBlockItemIndex(-1);
					blocks[selectRow + 1][selectColumn + 1]
							.setBlockItemIndex(-1);
					blocks[row + 1][column + 1].explodeNode();
					blocks[selectRow + 1][selectColumn + 1].explodeNode();

					isSelected = false;
					boolean isFinish = GameManager.instance.clearCouple();

					if (!isFinish) {
						// 监测是否需要重排，增加重排提醒
						Thread tryFindThread = new Thread() {
							public void run() {
								if (!findMatchBlocks(false)
										&& !GameManager.instance.isPaused()) {
									if (ShopManager.instance.assertInfo
											.getReArrangeCount() > 0) {
										// 重排
										ShopManager.instance.assertInfo
												.setReArrangeCount(ShopManager.instance.assertInfo
														.getReArrangeCount() - 1);
										ShopManager.instance.saveMyAssert();
										reArrange();
										GameScene.make().updateTool();

									} else {
										// 提示重排,显示暂停界面
										GameScene.make().pauseGame();
									}
								}
							};
						};
						tryFindThread.start();
					}

					// 清除提示标识
					if (spriteFinder1 != null && spriteFinder2 != null) {
						spriteFinder1.setVisible(false);
						spriteFinder2.setVisible(false);
						isFinderShow = false;
					}
				}
			}

			if (itemCurrent >= 0 && (!isSameItem || !isLined)) {
				float imageX = ResolutionIndependent
						.resolveDp(GameSystem.Margin_Side
								+ GameSystem.BLOCK_SIZE * column);
				float imageY = GameSystem.Start_Height
						+ ResolutionIndependent.resolveDp(GameSystem.BLOCK_SIZE
								* row);
				WYPoint pointSelect = WYPoint.make(imageX, imageY);

				if (isSelected) {
					GameManager.instance.comboBreak();
				}

				isSelected = true;
				selectRow = row;
				selectColumn = column;
				if (spriteSelector == null) {
					spriteSelector = Sprite.make(GameSystem.selectorTex);
					layer.addChild(spriteSelector);
					spriteSelector.setAnchorPercent(0, 0);
					spriteSelector.setPosition(pointSelect);
				} else {
					spriteSelector.setPosition(pointSelect);
					layer.removeChild(spriteSelector, true);
					spriteSelector.setVisible(true);
					layer.addChild(spriteSelector);
				}
			}
		}
	}

	public synchronized static boolean findMatchBlocks(boolean isShowFinder) {
		if (!isFinderShow) {
			List<Location> locations = findCouple();
			if (locations != null && locations.size() == 2) {
				if (isShowFinder) {
					// 使用帮助工具后 ,combo重置
					GameManager.instance.comboBreak();

					Location l1 = locations.get(0);
					Location l2 = locations.get(1);
					setFinder(l1, 1);
					setFinder(l2, 2);
					isFinderShow = true;
				}
				return true;
			}
			return false;
		} else {
			return false;
		}
	}

	/**
	 * 设置finder的位置
	 * 
	 * @param l
	 * @param finder
	 */
	private static void setFinder(Location l, int finderIndex) {
		float imageX = ResolutionIndependent.resolveDp(GameSystem.Margin_Side
				+ GameSystem.BLOCK_SIZE * l.getColumn());
		float imageY = GameSystem.Start_Height
				+ ResolutionIndependent.resolveDp(GameSystem.BLOCK_SIZE
						* l.getRow());
		WYPoint pointFinder = WYPoint.make(imageX, imageY);
		if (finderIndex == 1) {
			if (spriteFinder1 == null) {
				spriteFinder1 = Sprite.make(GameSystem.finderTex);
				layer.addChild(spriteFinder1);
				spriteFinder1.setAnchorPercent(0, 0);
				spriteFinder1.setPosition(pointFinder);
			} else {
				spriteFinder1.setPosition(pointFinder);
				spriteFinder1.setVisible(true);
				layer.removeChild(spriteFinder1, true);
				layer.addChild(spriteFinder1);
			}
		} else {
			if (spriteFinder2 == null) {
				spriteFinder2 = Sprite.make(GameSystem.finderTex);
				layer.addChild(spriteFinder2);
				spriteFinder2.setAnchorPercent(0, 0);
				spriteFinder2.setPosition(pointFinder);
			} else {
				spriteFinder2.setPosition(pointFinder);
				spriteFinder2.setVisible(true);
				layer.removeChild(spriteFinder2, true);
				layer.addChild(spriteFinder2);
			}
		}
	}

	/**
	 * 找出可能匹配的Block
	 * 
	 * @return
	 */
	private static List<Location> findCouple() {
		List<Location> result = new ArrayList<Location>();
		for (int i = 1; i < GameSystem.GameRows + 1; i++) {
			for (int j = 1; j < GameSystem.GameColumns + 1; j++) {
				LLKBlock block = blocks[i][j];
				if (block.getBlockItemIndex() >= 0) {
					LLKBlock matchBlock = findMatchBlock(block, i, j);
					if (matchBlock != null) {
						// 找到了
						result.add(block.getLocation());
						result.add(matchBlock.getLocation());
						return result;
					}

				}
			}
		}
		return null;
	}

	private synchronized static LLKBlock findMatchBlock(LLKBlock block, int ii,
			int jj) {
		for (int i = 1; i < GameSystem.GameRows + 1; i++) {
			for (int j = 1; j < GameSystem.GameColumns + 1; j++) {
				LLKBlock match = blocks[i][j];
				if (match.getBlockItemIndex() < 0) {
					continue;
				}
				if (ii == i && jj == j) {
					continue;
				}

				if (block.getBlockItemIndex() == match.getBlockItemIndex()) {
					// 尝试匹配
					boolean isLined = LLKLogicHelper.CanEliminate(blocks, i, j,
							ii, jj);
					if (isLined) {
						return blocks[i][j];
					}
				}
			}
		}
		return null;
	}

	public synchronized static void reArrange() {
		// 使用帮助工具后 ,combo重置, 取消之
		// GameManager.instance.comboBreak();

		// 重新洗牌，并修改LLKBlock对象中的Location
		// 找到所有没有被消除的块
		List<Integer> iList = new ArrayList<Integer>();
		List<Integer> jList = new ArrayList<Integer>();
		for (int i = 1; i < GameSystem.GameRows + 1; i++) {
			for (int j = 1; j < GameSystem.GameColumns + 1; j++) {
				if (blocks[i][j].getBlockItemIndex() >= 0) {
					iList.add(i);
					jList.add(j);
				}
			}
		}

		// 随机进行互换
		int halfCount = iList.size() / 2;
		for (int k = 0; k < halfCount; k++) {
			int i1 = iList.get(k);
			int j1 = jList.get(k);
			int randomK = halfCount + r.nextInt(halfCount);
			int i2 = iList.get(randomK);
			int j2 = jList.get(randomK);

			// 进行互换
			LLKBlock temp = blocks[i1][j1];
			blocks[i1][j1] = blocks[i2][j2];
			blocks[i2][j2] = temp;

			// 更新Location
			blocks[i1][j1].setLocation(new Location(i1 - 1, j1 - 1));
			blocks[i2][j2].setLocation(new Location(i2 - 1, j2 - 1));
		}
	}

	/**
	 * 爆炸动画结束后处理节点移动
	 * 
	 * @param row
	 * @param cloumn
	 */
	public static synchronized void moveNode(int row, int cloumn) {
		NodeMoveHelper.moveNode(blocks, row + 1, cloumn + 1,
				GameManager.instance.ArrangeType);
	}
}
